﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using ShengYueWorkShop.BLL.PublicHelper;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using Microsoft.Win32;
using ShengYueWorkShop.BLL.Tcp;

namespace ShengYueWorkShop.TcpServer
{
    public partial class TcpFrm : Form
    {
        #region
        /// <summary>
        /// 服务器的IP地址
        /// </summary>
        private IPAddress _ServerIP;
        /// <summary>
        /// 服务器的端口
        /// </summary>
        private int _ServerPort;

        /// <summary>
        /// TCP服务
        /// </summary>
        private ServerHelper _ServerHelper;
        private System.Timers.Timer _IpCheckTimer;
        private BLL.DataModel.WS_FtpServer _DataModel { get; set; }
        private bool _IpChangedFlag = false;
        #endregion

        public TcpFrm()
        {
            InitializeComponent();
            this.FormClosed += TcpFrm_FormClosed;
            this.SizeChanged += Shown_SizeChanged;
            notifyIcon1.DoubleClick += NotifyIcon1_DoubleClick;
            this.Shown += TcpFrm_Shown;
        }

        #region 窗口最大、最小、退出事件
        private void NotifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.ShowInTaskbar = true;  //显示在系统任务栏
                this.WindowState = FormWindowState.Normal;  //还原窗体
                notifyIcon1.Visible = false;  //托盘图标隐藏
            }
        }

        private void Shown_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)  //判断是否最小化
            {
                this.ShowInTaskbar = false;  //不显示在系统任务栏
                notifyIcon1.Visible = true;  //托盘图标可见
            }
        }

        /// <summary>
        /// 程序关闭
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TcpFrm_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (KJ_LogRichText.Text.Length > 0)
            {
                WriteLogForFile.WirteTxt(KJ_LogRichText.Text);
            }
            if (_ServerHelper != null)
            {
                _ServerHelper.ListenerStop();
            }
            Application.Exit();
        }
        #endregion

        private void TcpFrm_Shown(object sender, EventArgs e)
        {
            Btn_SaveConfig.Click += Btn_SaveConfig_Click;
            Btn_SqlConfig.Click += Btn_SaveConfig_Click;
            Btn_StarServer.Click += Btn_SaveConfig_Click;
            if (LoadAppConfig())
            {
                //开机启动
                if (KJ_SystemStar.Checked == true)
                {
                    Btn_SaveConfig_Click(Btn_StarServer, null);
                }
            }
            else
            {
                MessageBox.Show("服务器配置错误！");
                SqlView frm = new SqlView();
                frm.ShowDialog();
            }
        }

        /// <summary>
        /// 按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_SaveConfig_Click(object sender, EventArgs e)
        {
            Button fBtn = (Button)sender;
            if ("启动服务" == fBtn.Text)
            {
                IpCheck(true);
            }
            else if ("停止服务" == fBtn.Text)
            {
                IpCheck(false);
            }
            else if ("重启服务" == fBtn.Text)
            {
                IpCheck(false);
                IpCheck(true);
            }
            else if ("保存参数" == fBtn.Text)
            {
                SaveConfig();
            }
            else if ("数据配置" == fBtn.Text)
            {
                SqlView frm = new SqlView();
                frm.ShowDialog();
            }
        }
        private void TcpServerStar()
        {
            if (_IpChangedFlag)
            {
                try
                {
                    TcpOperationCommand.PicMaxMb = Convert.ToDouble(KJ_PicMaxMb.Value);
                    TcpOperationCommand.PicPercent = Convert.ToDouble(KJ_PicPercent.Value) / 100;

                    _ServerHelper = new ServerHelper();
                    _ServerHelper.ListenerStar(
                        _ServerIP,
                        _ServerPort,
                        KJ_Token.Text.Trim(),
                        KJ_LogRichText);
                }
                catch (Exception ex)
                {
                    Btn_StarServer.Text = "启动服务";
                    LogWrite(ex.ToString());
                }
            }
            else
            {
                LogWrite("参数错误，服务未能启动......");
            }
        }
        private void IpCheck(bool IsStart)
        {
            if (IsStart)
            {
                //每次启动服务时重新计算新的Token
                KJ_Token.Text = OtherFun.CreateToken();
                //先立即处理数据后开启定时任务
                IpChanged(null, null);
                _IpCheckTimer = new System.Timers.Timer();
                double de = Convert.ToDouble(5 * 60 * 1000);
                _IpCheckTimer = new System.Timers.Timer(de);//定时周期
                _IpCheckTimer.Elapsed += IpChanged;//到了周期时执行清理事件
                _IpCheckTimer.AutoReset = true; //是否不断重复定时器操作
                _IpCheckTimer.Enabled = true; //定时器开始用
                                              //如果不写下面这句会有一个异常。
                                              //异常：线程间操作无效: 从不是创建控件"richtextbox"的线程访问它
                                              //但这不是最好的方法。如果只有一个进程调用richtextbox而已。就可以用下面这句
                                              //如果有多个线程调用richtextbox等控件。就要用委托。具体百度
                                              //一篇参考博客http://www.cnblogs.com/zyh-nhy/archive/2008/01/28/1056194.html
                Control.CheckForIllegalCrossThreadCalls = false;
                Thread TcpThread = new Thread(TcpServerStar);
                TcpThread.Start();
                TcpThread.IsBackground = true;
                Btn_StarServer.Text = "停止服务";
            }
            else
            {
                _ServerHelper.ListenerStop();
                _IpCheckTimer?.Stop();
                //LogWrite("服务已经停止……");
                Btn_StarServer.Text = "启动服务";
            }
        }
        private void IpChanged(object sender, System.Timers.ElapsedEventArgs e)
        {
            _IpChangedFlag = false;
            //获取指定IP段的IP地址，用于有多个IP地址的服务器
            List<string> fIpList = new List<string>();
            fIpList = OtherFun.GetLocalIPAddress();
            foreach (string fIp in fIpList)
            {
                if (fIp.Contains(KJ_ServerQianZui.Text))
                {
                    KJ_ServerIP.Text = fIp;
                }
            }

            //启动验证
            if (KJ_ServerIP.Text.Length == 0 || KJ_ServerPort.Value == 0)
            {
                LogWrite("启动失败,请设置IP地址或端口");
                return;
            }
            if (KJ_Token.Text.Length == 0)
            {
                LogWrite("请设置token令牌");
                return;
            }
            if (!IPAddress.TryParse(KJ_ServerIP.Text.Trim(), out _ServerIP))
            {
                LogWrite("启动失败,请正确设置IP地址");
                return;
            }
            if (!int.TryParse(KJ_ServerPort.Value.ToString(), out _ServerPort))
            {
                LogWrite("启动失败,请正确设置端口");
                return;
            }

            bool fIsUpdate = true;
            _IpChangedFlag = true;
            if (_DataModel != null)
            {
                if (_DataModel.MachineID == KJ_ServerName.Text.Trim() &&
                    _DataModel.ServerIP == KJ_ServerIP.Text.Trim() &&
                    _DataModel.ServerPort == KJ_ServerPort.Value.ToString() &&
                    _DataModel.Token == KJ_Token.Text.Trim())
                {
                    fIsUpdate = false;
                }
            }
            if (fIsUpdate)
            {
                _DataModel = new BLL.DataModel.WS_FtpServer();
                _DataModel.MachineID = KJ_ServerName.Text.Trim();
                _DataModel.ServerIP = KJ_ServerIP.Text.Trim();
                _DataModel.ServerPort = KJ_ServerPort.Value.ToString();
                _DataModel.Token = KJ_Token.Text.Trim();
                _DataModel.UID = "";
                _DataModel.PWD = "";

                SqlHelper fSqlHelper = new SqlHelper();
                if (fSqlHelper.UpdateServer(_DataModel))
                {
                    LogWrite("服务器参数变更完成……");
                }
                else
                {
                    LogWrite("上传服务器数据失败……");
                }
                if ("停止服务" == Btn_StarServer.Text)
                {
                    //重启服务
                    Btn_StarServer.Text = "重启服务";
                    Btn_SaveConfig_Click(Btn_StarServer, null);
                }
            }
        }
        private void SaveConfig()
        {
            try
            {
                if (KJ_ServerName.Text.Trim().Length > 0)
                {
                    AppConfig.WriteValue_Encry(KJ_ServerName.Text.Trim(), "MachineID");
                }
                if (KJ_ServerPort.Text.Trim().Length >= 0)
                {
                    AppConfig.WriteValue_Encry(KJ_ServerPort.Text.Trim(), "Port");
                }
                if (KJ_PicPercent.Text.Trim().Length >= 0)
                {
                    AppConfig.WriteValue_Encry(KJ_PicPercent.Text.Trim(), "PicPercent");
                }
                if (KJ_PicMaxMb.Text.Trim().Length >= 0)
                {
                    AppConfig.WriteValue_Encry(KJ_PicMaxMb.Text.Trim(), "PicMaxMb");
                }
                if (KJ_ServerQianZui.Text.Trim().Length >= 0)
                {
                    AppConfig.WriteValue_Encry(KJ_ServerQianZui.Text.Trim(), "IPQianZui");
                }
                AppConfig.WriteValue_Encry(KJ_SystemStar.Checked.ToString(), "SystemStar");
                if (KJ_SystemStar.Checked)
                {
                    //MessageBox.Show("设置开机自启动，需要修改注册表", "提示");
                    string path = Application.ExecutablePath;
                    RegistryKey rk = Registry.LocalMachine;
                    RegistryKey rk2 = rk.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");
                    rk2.SetValue("ShengYueWorkShop", path);
                    rk2.Close();
                    rk.Close();
                }
                else
                {
                    //MessageBox.Show("取消开机自启动，需要修改注册表", "提示");
                    string path = Application.ExecutablePath;
                    RegistryKey rk = Registry.LocalMachine;
                    RegistryKey rk2 = rk.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");
                    rk2.DeleteValue("ShengYueWorkShop", false);
                    rk2.Close();
                    rk.Close();
                }
                MessageBox.Show("保存成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
        private bool LoadAppConfig()
        {
            try
            {
                KJ_ServerName.Text = AppConfig.GetValue_Decrypt("MachineID");
                KJ_ServerPort.Text = AppConfig.GetValue_Decrypt("Port");
                KJ_ServerQianZui.Text = AppConfig.GetValue_Decrypt("IPQianZui");
                KJ_PicMaxMb.Text = AppConfig.GetValue_Decrypt("PicMaxMb");
                KJ_PicPercent.Text = AppConfig.GetValue_Decrypt("PicPercent");
                string fChecked = AppConfig.GetValue_Decrypt("SystemStar");
                if (fChecked.Length > 0)
                {
                    KJ_SystemStar.Checked = Convert.ToBoolean(fChecked);
                }
                SqlHelper._SqlConn = AppConfig.GetValue_Decrypt("SqlConn");
                if (SqlHelper._SqlConn.Length == 0)
                {
                    return false;
                }

                return true;
            }
            catch
            {
                MessageBox.Show("读取配置文件错误!");
                return false;
            }
        }
        private void LogWrite(string pLogStr)
        {
            if (KJ_LogRichText.Text.Length > 50000)
            {
                KJ_LogRichText.Text = "";
                KJ_LogRichText.Text += string.Format("{0} 清空日志\r\n", DateTime.Now);
            }
            if (KJ_LogRichText.Text.Length > 0)
            {
                KJ_LogRichText.Text += "\r\n";
            }
            KJ_LogRichText.Text += string.Format("{0} {1}", DateTime.Now, pLogStr);
            //光标定位在最后一行
            KJ_LogRichText.SelectionStart = KJ_LogRichText.Text.Length;
            KJ_LogRichText.SelectionLength = 0;
            KJ_LogRichText.ScrollToCaret();
        }

    }
}